package com.bluetooth.phone;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SoundEffectConstants;
import android.view.View;

import androidx.databinding.BindingAdapter;

import com.hsae.bluetooth.phones.R;

public class ManualFanLevel extends View {
    private final String TAG = "ManualFanLevel";

    private volatile int mMaxLevel = 8;

    private volatile int mBlockWith = 40;

    private int mBlockHeight = 18;

    private int mBlockDivideWidth = 8;

    private volatile int mCurrentRealLevel = 0;

    private volatile int mCurrentLevel = 0;

    private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    private final Point mCoo = new Point();
    private final Path mPath = new Path();

    private int mActiveColor;

    private int mUnActiveColor;

    private float mProgressPercent = 0.33f;
    private boolean mEnable = true;
    private FanLevelChangeListener mFanLevelChangeListener;

    private boolean mIsTouch = false;

    public interface FanLevelChangeListener {
        void onChange(ManualFanLevel fanLevel, int level);
    }

    public ManualFanLevel(Context context) {
        this(context, null);
    }

    public ManualFanLevel(Context context, AttributeSet attrs) {
        this(context, attrs, 0);

    }

    public ManualFanLevel(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    private void init(Context context, AttributeSet attrs) {
        if (attrs == null) {
            return;
        }
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.FanLevel);
        mActiveColor = typedArray.getColor(R.styleable.FanLevel_fanLevelActiveColor, Color.TRANSPARENT);
        mUnActiveColor = typedArray.getColor(R.styleable.FanLevel_fanLevelUnActiveColor, Color.TRANSPARENT);
        mBlockDivideWidth = typedArray.getDimensionPixelSize(R.styleable.FanLevel_fanLevelBlockDividerWidth, 3);
        mBlockHeight = typedArray.getDimensionPixelSize(R.styleable.FanLevel_fanLevelBlockHeight, 8);
        typedArray.recycle();
        mPaint.setColor(mActiveColor);
        mPaint.setStrokeWidth(1f);
        mPaint.setStyle(Paint.Style.FILL);

    }

    @BindingAdapter({"bindMaxLevel"})
    public static void bindMaxLevel(ManualFanLevel fanLevel, int maxLevel) {
        fanLevel.setMaxLevel(maxLevel);
    }

    @BindingAdapter({"bindCurrentLevel"})
    public static void bindCurrentLevel(ManualFanLevel fanLevel, int currentLevel) {
        fanLevel.setCurrentLevel(currentLevel);
    }

    @BindingAdapter({"bindFanLevelEnable"})
    public static void bindFanLevelEnable(ManualFanLevel fanLevel, boolean enable) {
        fanLevel.setEnabled(enable);
    }

    @BindingAdapter({"bindFanLevelChangeListener"})
    public static void bindFanLevelChangeListener(ManualFanLevel fanLevel,
                                                  FanLevelChangeListener listener) {
        fanLevel.setFanLevelChangeListener(listener);

    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);//view size计算完毕，需要更新尺寸
        calculateDimens();
        mCoo.y = h / 2;
    }

    private void calculateDimens() {
        int totalWidth = getWidth();
        try {
            mBlockWith = (totalWidth - mBlockDivideWidth * (mMaxLevel - 1)) / mMaxLevel;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public void setFanLevelChangeListener(FanLevelChangeListener FanLevelChangeListener) {
        mFanLevelChangeListener = FanLevelChangeListener;
    }

    public void setMaxLevel(int maxLevel) {
//        if (mMaxLevel == maxLevel) {
//            return;
//        }

        mMaxLevel = maxLevel;
//mMaxLevel发生变化，需要重新计算
        if (mCurrentRealLevel > mMaxLevel) {
            mCurrentLevel = mMaxLevel;
        } else {
            mCurrentLevel = mCurrentRealLevel;
        }
        calculateDimens();
        invalidate();
    }


    public void setCurrentLevel(int currentLevel) {

        mCurrentRealLevel = currentLevel;
//
//        if (mCurrentLevel == currentLevel) {
//            return;
//        }
        if (currentLevel < 0 || mIsTouch) {
            return;
        }
        if (currentLevel > mMaxLevel) {
            mCurrentLevel = mMaxLevel;
        } else {
            mCurrentLevel = currentLevel;
        }
        invalidate();

    }

    @Override
    public void setEnabled(boolean enabled) {
        mEnable = enabled;
        super.setEnabled(enabled);
        invalidate();
    }

    private void addPath(Path path, int blockIndex) {
        int halfBlockHeight = mBlockHeight / 2;
        int blockWith = mBlockWith;
        int maxLevel = mMaxLevel;
        int blockDivideWidth = mBlockDivideWidth;

//        if (blockIndex == 0) {
//            path.addCircle(halfBlockHeight, 0, halfBlockHeight, Path.Direction.CW);
//            path.addRect(halfBlockHeight, -halfBlockHeight, blockWith, halfBlockHeight, Path.Direction.CW);
//        } else if (blockIndex == maxLevel - 1) {
//            int left = blockWith * (maxLevel - 1) + blockDivideWidth * (maxLevel - 1);
//            int right = blockWith * maxLevel + blockDivideWidth * (maxLevel - 1);
//
//            path.addCircle(
//                    right - halfBlockHeight,
//                    0,
//                    halfBlockHeight,
//                    Path.Direction.CW
//            );
//            path.addRect(
//                    left,
//                    -halfBlockHeight,
//                    right - halfBlockHeight,
//                    halfBlockHeight,
//                    Path.Direction.CW);
//        } else {
            path.addRect(blockWith * blockIndex + blockDivideWidth * blockIndex,
                    -halfBlockHeight,
                    blockWith * (blockIndex + 1) + blockDivideWidth * blockIndex,
                    halfBlockHeight,
                    Path.Direction.CW);
    //    }
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Log.d(TAG, "onDraw active:" + mActiveColor + ",unactive:" + mUnActiveColor);
        canvas.translate(mCoo.x, mCoo.y);
        if (mEnable) {
            mPath.reset();
            mPaint.setColor(mActiveColor);
            for (int i = 0; i < mCurrentLevel; i++) {
                addPath(mPath, i);
            }
            canvas.drawPath(mPath, mPaint);
            mPaint.setColor(mUnActiveColor);
            mPath.reset();
            for (int i = mCurrentLevel; i < mMaxLevel; i++) {
                addPath(mPath, i);
            }
        } else {
            mPaint.setColor(mUnActiveColor);
            mPath.reset();
            for (int i = 0; i < mMaxLevel; i++) {
                addPath(mPath, i);
            }
        }
        canvas.drawPath(mPath, mPaint);
    }

    private void calculateProgress(MotionEvent event) {
        calculateProgress(event, false);
    }

    private void calculateProgress(MotionEvent event, boolean forceCallBack) {
        float x = event.getX();
        int progress = (int) (1 + (x - mProgressPercent * mBlockWith) / (mBlockWith + mBlockDivideWidth));
        if (progress > mMaxLevel) {
            progress = mMaxLevel;
        }
        Log.e("111",progress+"....##");

        if (progress <= 0) {
            progress = 1;
        }
        if (!forceCallBack && progress == mCurrentLevel) {
            return;
        }

        mCurrentLevel = progress;
        invalidate();
        if (!forceCallBack) {
            playSound();
        }
        if (mFanLevelChangeListener != null) {
            mFanLevelChangeListener.onChange(this, mCurrentLevel);


        }
    }


    private void playSound() {
        playSoundEffect(SoundEffectConstants.getContantForFocusDirection(FOCUS_DOWN));
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (!mEnable) {
            return false;
        }
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mIsTouch = true;
                getParent().requestDisallowInterceptTouchEvent(true);
                calculateProgress(event);
                break;
            case MotionEvent.ACTION_MOVE:
                calculateProgress(event);
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                mIsTouch = false;
                calculateProgress(event, true);
                break;
        }
        return true;
    }


}























